package com.zenithmind.note.pojo.entity;

import com.baomidou.mybatisplus.annotation.*;
import com.zenithmind.common.base.BaseEntity;
import com.zenithmind.note.pojo.enums.NoteStatus;
import com.zenithmind.note.pojo.valueobject.NoteStatistics;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import jakarta.validation.constraints.NotNull;

/**
 * 笔记实体类
 * 遵循面向对象设计原则：
 * 1. 单一职责：只负责笔记数据的存储和基本业务逻辑
 * 2. 封装性：提供业务方法而不是直接暴露字段操作
 * 3. 不变性：某些关键字段创建后不可修改
 */
@EqualsAndHashCode(callSuper = true)
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Schema(name = "笔记实体", description = "笔记实体")
public class Note extends BaseEntity {

    @NotNull(message = "用户ID不能为空")
    @Schema(description = "用户ID")
    private String userId;

    @Schema(description = "课程ID")
    private String courseId;

    @Schema(description = "分类ID")
    private String categoryId;

    @NotBlank(message = "笔记标题不能为空")
    @Size(max = 100, message = "笔记标题长度不能超过100个字符")
    @Schema(description = "笔记标题")
    private String title;

    @Schema(description = "笔记内容")
    @TableField("content")
    private String content;

    @Schema(description = "笔记标签")
    @Size(max = 255, message = "笔记标签长度不能超过255个字符")
    private String tags;

    @Schema(description = "状态")
    private Integer status;

    @Schema(description = "浏览次数")
    private Integer viewCount;

    @Schema(description = "点赞次数")
    private Integer likeCount;

    @Schema(description = "评论次数")
    private Integer commentCount;

    // ==================== 业务方法 ====================

    /**
     * 获取笔记状态枚举
     *
     * @return 笔记状态
     */
    public NoteStatus getNoteStatus() {
        return NoteStatus.fromCode(this.status);
    }

    /**
     * 设置笔记状态
     *
     * @param noteStatus 笔记状态
     */
    public void setNoteStatus(NoteStatus noteStatus) {
        this.status = noteStatus != null ? noteStatus.getCode() : null;
    }

    /**
     * 获取统计信息值对象
     *
     * @return 统计信息
     */
    public NoteStatistics getStatistics() {
        return NoteStatistics.builder()
                .viewCount(this.viewCount != null ? this.viewCount : 0)
                .likeCount(this.likeCount != null ? this.likeCount : 0)
                .commentCount(this.commentCount != null ? this.commentCount : 0)
                .favoriteCount(0) // 需要从其他表查询
                .shareCount(0)    // 需要从其他表查询
                .build();
    }

    /**
     * 更新统计信息
     *
     * @param statistics 新的统计信息
     */
    public void updateStatistics(NoteStatistics statistics) {
        if (statistics != null) {
            this.viewCount = statistics.getViewCount();
            this.likeCount = statistics.getLikeCount();
            this.commentCount = statistics.getCommentCount();
        }
    }

    /**
     * 判断是否可以被查看
     *
     * @return 是否可查看
     */
    public boolean isViewable() {
        NoteStatus noteStatus = getNoteStatus();
        return noteStatus != null && noteStatus.isValid();
    }

    /**
     * 判断是否可以被编辑
     *
     * @param currentUserId 当前用户ID
     * @return 是否可编辑
     */
    public boolean isEditableBy(String currentUserId) {
        if (currentUserId == null || !currentUserId.equals(this.userId)) {
            return false;
        }

        NoteStatus noteStatus = getNoteStatus();
        return noteStatus != null && noteStatus.isEditable();
    }

    /**
     * 判断是否可以被删除
     *
     * @param currentUserId 当前用户ID
     * @return 是否可删除
     */
    public boolean isDeletableBy(String currentUserId) {
        if (currentUserId == null || !currentUserId.equals(this.userId)) {
            return false;
        }

        NoteStatus noteStatus = getNoteStatus();
        return noteStatus != null && noteStatus.isDeletable();
    }

    /**
     * 发布笔记
     *
     * @throws IllegalStateException 如果笔记状态不允许发布
     */
    public void publish() {
        NoteStatus currentStatus = getNoteStatus();
        if (currentStatus == null || !currentStatus.isEditable()) {
            throw new IllegalStateException("当前状态不允许发布笔记");
        }

        setNoteStatus(NoteStatus.PUBLISHED);
    }

    /**
     * 撤回到草稿状态
     *
     * @throws IllegalStateException 如果笔记状态不允许撤回
     */
    public void revertToDraft() {
        NoteStatus currentStatus = getNoteStatus();
        if (currentStatus == NoteStatus.DELETED) {
            throw new IllegalStateException("已删除的笔记不能撤回到草稿状态");
        }

        setNoteStatus(NoteStatus.DRAFT);
    }

    /**
     * 删除笔记（软删除）
     */
    public void delete() {
        setNoteStatus(NoteStatus.DELETED);
    }

    /**
     * 初始化新笔记的默认值
     */
    public void initializeDefaults() {
        if (this.viewCount == null) {
            this.viewCount = 0;
        }
        if (this.likeCount == null) {
            this.likeCount = 0;
        }
        if (this.commentCount == null) {
            this.commentCount = 0;
        }
        if (this.status == null) {
            setNoteStatus(NoteStatus.DRAFT);
        }
    }
}